home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 239_01 / bg3.c < prev    next >
Text File  |  1987-07-29  |  26KB  |  840 lines

  1.  
  2. /*
  3. **  bg3.c -- gameplan
  4. */
  5.  
  6. #include "backgmmn.h"
  7.  
  8.  
  9. /*=============================================*/
  10. /*     M Y   M O V E                           */
  11. /*=============================================*/
  12.  
  13.  
  14. static naked() {  /* am I leaving too many blots? */
  15. static int i, clink;
  16.      i = 24;  clink = 0;
  17.      while (i) {
  18.           if (point[i].stones == 1 && point[i].owner == ME) clink++;
  19.           i--;
  20.      }
  21.      return (clink > 2);
  22. } /* end: naked */
  23.  
  24.  
  25. static yourfolly() { /* look for lotsa blots in your inner table */
  26. static int i, clink;
  27.      i = 18; clink = 0;
  28.      while (i < 25) {
  29.           if (point[i].owner == YU && point[i].stones == 1) 
  30.                clink++; 
  31.           i++;
  32.      }
  33.      return (clink >= 3);
  34. } /* end: yourfolly */
  35.  
  36.  
  37. static goodboard() { /* look for four made points near my inner table */
  38. static int i, clank, clink;
  39.      i = 9; clank = 0;
  40.      while (i > 3) {
  41.           if (point[i].owner == ME && point[i].stones > 1) clank++;
  42.           i--;
  43.      }
  44.      if (clank > 4) return (TRUE);  /* bar is nearly blocked */
  45.  
  46.      i = 6; clank = clink = 0;
  47.      while (i) {
  48.           if (point[i].owner != ME) 
  49.                ;
  50.           else if (point[i].stones == 1) clink++; else clank++;
  51.           i--;
  52.      }
  53.      return (clank > 3 && clink < 2);
  54. } /* end: goodboard */
  55.  
  56.  
  57. static scanahead( from ) int from; {
  58. static int count;
  59.  
  60.      count = 0;
  61.      while (--from > 0) {
  62.           ++count;
  63.           if ( point[ from ].owner == YU ) return (count);
  64.      }
  65.      return (7);
  66.  
  67. } /* end: scanahead */
  68.  
  69.  
  70.  
  71.  
  72. /*------------------------------------------------------------*/
  73. /* MATCHUP                                                    */
  74. /*                                                            */
  75. /* 2-stone functions that force the choice of the next move.  */
  76. /* These are the HEART and SOUL of this backgammon algorithm! */
  77. /*------------------------------------------------------------*/
  78.  
  79. static setpend( from, to ) int from, to; {
  80.      pending.fr   = from;
  81.      pending.to   = to;
  82.      pending.flag = TRUE;
  83. } /* end: setpend */
  84.  
  85.  
  86. static natural(f1,t1,f2,t2) int f1,t1,f2,t2; {
  87.      clrpend();
  88.      if (point[t2].stones == 1 && t1 == f2) setpend(f2,t2);
  89.      return (pending.flag);
  90. } /* end: natural */
  91.  
  92.  
  93. static matchup( test4 ) int (* test4)(); {
  94. static int i, j, ti, tj;
  95.  
  96.      if ( pending.flag ) return (FALSE); /* this is probably redundant */
  97.  
  98.      for (i = 1; i < 26; i++) {
  99.           ti = list[0][i];
  100.           if ( ti == ERROR ) goto zoo;
  101.           for (j = 1; j < 26; j++) {
  102.                tj = list[1][j];
  103.                if ( tj == ERROR ) goto voo;
  104.                if ( (* test4)( i, ti, j, tj ) ) {
  105.                     lurch( i, ti, 0);
  106.                     return (TRUE);
  107.                }
  108.              voo: ;
  109.           }
  110.         zoo: ;
  111.      }
  112.      return (FALSE);
  113.  
  114. } /* end: matchup */
  115.  
  116.  
  117. static matchhi( test4 ) int (* test4)(); {
  118. static int i, j, ti, tj;
  119.  
  120.      if ( pending.flag ) return (FALSE); /* this is probably redundant */
  121.  
  122.      for (i = 1; i < 26; i++) {
  123.           ti = list[1][i];
  124.           if ( ti == ERROR ) goto zoo;
  125.           for (j = 1; j < 26; j++) {
  126.                tj = list[0][j];
  127.                if ( tj == ERROR ) goto voo;
  128.                if ( (* test4)( i, ti, j, tj ) ) {
  129.                     lurch( i, ti, 1);
  130.                     return (TRUE);
  131.                }
  132.              voo: ;
  133.           }
  134.         zoo: ;
  135.      }
  136.      return (FALSE);
  137.  
  138. } /* end: matchhi */
  139.  
  140.  
  141.  
  142. /*--------------------------------------------------------*/
  143. /* CLOCKWISE and COUNTERCLOCK                             */
  144. /*                                                        */
  145. /* the rest of these are single-stone decisions based on  */
  146. /* rules of thumb, board-scanning functions               */
  147. /*--------------------------------------------------------*/
  148.  
  149. static plainstupid( from ) int from; { /* don't break a safe point */
  150.      return (from < 13 && (point[from].stones == 2 && scanahead(from) < 7));
  151. } /* end: plainstupid */
  152.  
  153.  
  154. static unwise( innertablept ) int innertablept; {
  155.      /* if it's a hit, just for god's sake don't put him on the bar!! */
  156.      if ( innertablept < 7 ) {
  157.           if (point[ innertablept ].owner == YU ||
  158.               point[ YRBAR ].stones > 0) 
  159.                return (TRUE);
  160.      }
  161.      return(FALSE);
  162. } /* end: unwise */
  163.  
  164.  
  165.  
  166. static covermine( from, to ) int from, to; {
  167.      if ( from < 8 ) return(FALSE);
  168.      return ( (point[ to ].stones == 1) && (point[ to ].owner == ME) );
  169. } /* end: covermine */
  170.  
  171.  
  172. static idareyou( from, to ) int from, to; {
  173.      if (unwise( to )) return (FALSE);
  174.      if ( (point[ from ].stones != 2)
  175.           && (point[ to ].stones < 2)
  176.           && (scanahead( to ) > 6) ) return ( TRUE );
  177.      else return (FALSE);
  178. } /* end: idareyou */
  179.  
  180.  
  181. static hitandrun( from, to ) int from, to; {
  182.      return ( point[ to ].owner == YU );
  183. } /* end: hitandrun */
  184.  
  185.  
  186. static dbuild( from, to ) int from, to; {
  187. static int diceleft;
  188.      diceleft = (myturns? 2 + movesleft: movesleft);
  189.      if (diceleft > 1) {
  190.           /* can't possibly be only one stone on from point */
  191.           /* or kamikaze would have covered it on last move */
  192.           return ( point[to].stones == 0 );
  193.      }
  194.      return (FALSE);
  195. } /* end: dbuild */
  196.  
  197.  
  198. static kamikaze( from, to ) int from, to; { 
  199. /* cover my distant blot, or razzle-dazzle 'em with the long doubles hit */
  200. static int j, k, diceleft;
  201.      
  202.      k = from; 
  203.      j = from - to;
  204.      diceleft = myturns * movesleft;  /* NB: 2*2 == 2+2, "fourtunately" */
  205.      while ( diceleft-- ) {   /* predicting where doubles land is easy! */
  206.           k -= j;
  207.           if (k < 1) return (FALSE); /* out of bounds */
  208.           if ( point[ k ].stones == 0 ) continue;        /* simplify */
  209.           if ( point[ k ].stones == 1 )   /* found my blot or yours? */
  210.                return (TRUE);
  211.           else if ( point[k].owner == YU )   /* found your blockade? */
  212.                return (FALSE); 
  213.           else continue;        /* found my safe point, so ignore it */
  214.      }
  215.      return (FALSE);
  216.  
  217. } /* end: kamikaze */
  218.  
  219.  
  220. static hittite( from, to ) int from, to; {
  221.      return (hitandrun(from,to) && to > 9);
  222. } /* end: hittite */
  223.  
  224.  
  225. static safehit( from, to ) int from, to; {
  226.      return (hittite(from,to) && idareyou(from,to));
  227. } /* end: safehit */
  228.  
  229.  
  230. static foolsdemise( from, to ) int from, to; { 
  231.         /* annihilate orphaned blots in enemy's inner, my outer table */
  232.      return (to > 17 && point[to].owner == YU);
  233. } /* end: foolsdemise */
  234.  
  235.  
  236. static landonme( from, to ) int from, to; {
  237.      if ( plainstupid(from) ) return (FALSE);
  238.      if ( loneranger(from,to) ) {
  239.           if (from < 19 && to > 6) return(TRUE);
  240.      }
  241.      else return ( point[ to ].owner == ME && point[to].stones < 4);
  242. } /* end: landonme */
  243.  
  244.  
  245.  
  246. /* these evaluations have meaning only in the endgame */
  247.  
  248.  
  249. static nobackgammon( from, to ) int from, to; { /* endgame */
  250.      return (from > 19);
  251. } /* end: nobackgammon */
  252.  
  253.  
  254. static crosstable( from, to ) int from, to; { 
  255.      /* always move a table ahead if possible, in the endgame */
  256.      if (from < 7) return (FALSE);
  257.      if (from > 18 && to <= 18) return (TRUE);
  258.      if (from > 12 && to <= 12) return (TRUE);
  259.      if (from >  6 && to <=  6) return (TRUE);
  260.      return (FALSE);
  261. } /* end: crosstable */
  262.  
  263.  
  264. static fiftytworule( from, to ) int from, to; { /* endgame */
  265. static int p;
  266.      if (from < 7) return (FALSE);   /* not in inner table! */
  267.      p = from % 6;
  268.      if (p == 0) return (TRUE);            /* improve the six */
  269.      if (p != 5) return ( (to % 6) < 3 );    /* best improve under five */
  270. } /*  end: fiftytworule */
  271.  
  272.  
  273.  
  274.  
  275. /* these evaluations are universally applicable, last resort moves */
  276.  
  277.  
  278. static gohome( from, to ) int from, to; { /* always go home if you can */
  279.      return (to == MYHOME);
  280. } /* end: gohome */
  281.  
  282.  
  283. static scatter( from, to ) int from, to; {  /* scatter, esp. in the endgame */
  284.      if (plainstupid(from) || unwise(to)) return (FALSE);
  285.      return